package com.strongbj.iot.devices.dam.sub.dacai.response.handle;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.message.DAMMessageFactory;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessage;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessageType;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ButtonState;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnButtonControlEntity;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnButtonControlFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

public class SetSensorParamsHandle implements IMessageHandle<DaCaiMessage, Object> {
	private static Logger logger = LogManager.getLogger(OpenNetParamsPageHandle.class.getName());
	protected final static String COMMAND_CODE = "B111"; // 打开页面命令的编号
//	protected final static String NET_PAGE_INDEX = "0004";  	// 网络设置页面的索引
	protected final static byte[] DEFAULT_DEVICE_CODE = { 00, 00, 00 }; // 设备默认编号
	protected final static byte[] EMPTY_DATAS = {}; // 空参数
	protected final static long MAX_SET_AND_WAIT_MILLISECOND = 2000; // 最大等待并设置参数的毫秒数
	protected DAMMessageFactory damMessageFactory = new DAMMessageFactory();

	private ButtonState[] sensorStates = new ButtonState[12]; // 传感器状态
	private long prevGetTime; // 上一次获取数据的时间
	private ScreenReturnButtonControlEntity screenReturnButtonControlEntity;

	public SetSensorParamsHandle() {
		this.initScreenParams();
	}

	@Override
	public boolean isHandle(DaCaiMessage t) {
		if (t.getMessageType() == DaCaiMessageType.System && t.getCommand().equals(COMMAND_CODE)) {
			ScreenReturnButtonControlEntity sr = ScreenReturnButtonControlFactory.create(t.getDatas());

			// 如果控件类型为按钮，屏幕id为4，按钮id为1到13，就认为是打开网络界面
			if (sr != null && sr.getControlType() == 0x10 && sr.getScreenId() == 6
					&& (sr.getControlId() > 0 && sr.getControlId() < 14)) {
				this.screenReturnButtonControlEntity = sr;
				return true;
			}
		}
		return false;
	}

	private void initScreenParams() {
		for (int i = 0; i < this.sensorStates.length; i++) {
			this.sensorStates[i] = ButtonState.Unknow;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, DaCaiMessage t) {
		if (System.currentTimeMillis() - prevGetTime > MAX_SET_AND_WAIT_MILLISECOND) {
			initScreenParams();
		}
		ScreenReturnButtonControlEntity sr = ScreenReturnButtonControlFactory.create(t.getDatas());
		int index = sr.getControlId() - 1;
		this.sensorStates[index] = screenReturnButtonControlEntity.getButtonState();
		this.prevGetTime = System.currentTimeMillis();

		for (int i = 0; i < this.sensorStates.length; i++) {
			if (this.sensorStates[i] == ButtonState.Unknow)
				return null;
		}

		byte[] datas = this.SensorParamesEntity2Bytes(DEFAULT_DEVICE_CODE, this.sensorStates);
		ITaskManager taskManager = DAMManager.getTaskManager(t.getDamCode());
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {

			@Override
			protected void taskRun() {
				sendMessageToDAM(ctx.channel(), datas);
			}
		});

		initScreenParams(); // 发送后初始化屏幕
		return null;
	}

	/**
	 * 发送获取本地网络的消息
	 * 
	 * @param channel
	 */
	private void sendMessageToDAM(Channel channel, byte[] datas) {
		ByteBuf bs = Unpooled.copiedBuffer(datas);
		ChannelFuture cf = channel.writeAndFlush(bs);
		cf.addListener(new ChannelFutureListener() {

			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if (future.isSuccess()) {
					logger.info("DAM自动下发设置传感器类型命令成功 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				} else {
					logger.error("DAM自动下发传感器类型命令失败 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				}
			}
		});
	}

	/**
	 * 网络参数对象转byte数组
	 * 
	 * @param np
	 * @return
	 */
	private byte[] SensorParamesEntity2Bytes(byte[] devAddress, ButtonState[] sensorStates) {
		// 创建
		byte[] sensorTypeParamsDatas = new byte[7];
		// 设置传感器类型，dam里0为温度，1为温湿度
		for (int i = 0; i < sensorStates.length - 1; i += 2) {
			byte sensorType = 1;
			// 如果湿度传感器选中了，就将类型设置为温湿度传感器
			if (sensorStates[i + 1] == ButtonState.Up) {
				sensorType = 2;
			}
			sensorTypeParamsDatas[i / 2] = sensorType;
		}

		// 将命令发送到屏幕硬件
		byte[] datas = damMessageFactory.createDAMMessage(ByteUtil.longToBytes(System.currentTimeMillis()), devAddress, // 设备编号
				(byte) 0, // 设备类型，默认填0
				(byte) 0, // 版本号，默认填0
				(byte) 0x16, // 设置网络参数命令
				sensorTypeParamsDatas // 设置的网络参数数据
		); // 通过dam消息工厂获取设置网络参数的byte命令数组
		return datas;
	}
}